{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Exercise4-Answer.ipynb",
      "version": "0.3.2",
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "metadata": {
        "colab_type": "code",
        "id": "3NFuMFYXtwsT",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "import tensorflow as tf\n",
        "import os\n",
        "import zipfile\n",
        "\n",
        "DESIRED_ACCURACY = 0.999\n",
        "\n",
        "!wget --no-check-certificate \\\n",
        "    \"https://storage.googleapis.com/laurencemoroney-blog.appspot.com/happy-or-sad.zip\" \\\n",
        "    -O \"/tmp/happy-or-sad.zip\"\n",
        "\n",
        "zip_ref = zipfile.ZipFile(\"/tmp/happy-or-sad.zip\", 'r')\n",
        "zip_ref.extractall(\"/tmp/h-or-s\")\n",
        "zip_ref.close()\n",
        "\n",
        "class myCallback(tf.keras.callbacks.Callback):\n",
        "  def on_epoch_end(self, epoch, logs={}):\n",
        "    if(logs.get('acc')>DESIRED_ACCURACY):\n",
        "      print(\"\\nReached 99.9% accuracy so cancelling training!\")\n",
        "      self.model.stop_training = True\n",
        "\n",
        "callbacks = myCallback()\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "eUcNTpra1FK0",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "model = tf.keras.models.Sequential([\n",
        "    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 3)),\n",
        "    tf.keras.layers.MaxPooling2D(2, 2),\n",
        "    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n",
        "    tf.keras.layers.MaxPooling2D(2,2),\n",
        "    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n",
        "    tf.keras.layers.MaxPooling2D(2,2),\n",
        "    tf.keras.layers.Flatten(),\n",
        "    tf.keras.layers.Dense(512, activation='relu'),\n",
        "    tf.keras.layers.Dense(1, activation='sigmoid')\n",
        "])\n",
        "\n",
        "from tensorflow.keras.optimizers import RMSprop\n",
        "\n",
        "model.compile(loss='binary_crossentropy',\n",
        "              optimizer=RMSprop(lr=0.001),\n",
        "              metrics=['acc'])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "sSaPPUe_z_OU",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
        "\n",
        "train_datagen = ImageDataGenerator(rescale=1/255)\n",
        "\n",
        "train_generator = train_datagen.flow_from_directory(\n",
        "        \"/tmp/h-or-s\",  \n",
        "        target_size=(150, 150), \n",
        "        batch_size=10,\n",
        "        class_mode='binary')\n",
        "\n",
        "# Expected output: 'Found 80 images belonging to 2 classes'"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "0imravDn0Ajz",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "history = model.fit_generator(\n",
        "      train_generator,\n",
        "      steps_per_epoch=2,  \n",
        "      epochs=15,\n",
        "      verbose=1,\n",
        "      callbacks=[callbacks])"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}
